using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace LabyrinthProject
{
    enum PowerUpType
    {
        Cipela,
        Kompas,
        Skok,
        Zarulja,
        Upitnik
    }

    class PowerUp : IDrawable
    {
        #region constants
        private const float MAX_LIFE = 10;
        #endregion

        #region fields
        private PowerUpType typeOfPowerUp;
        private Model model;
        private Vector3 position;
        private BoundingBox boundingBox;

        private float lifeTime;

        private Matrix world;
        private float scaleFactor;
        private bool goUp;


        private Texture2D billboardTexture;
        private Quad quad;
        #endregion

        #region properties

        public float LifeTime
        {
            get { return lifeTime; }
            set { lifeTime = value; }
        }

        public BoundingBox BoundingBox
        {
            get { return boundingBox; }
            set { boundingBox = value; }
        }

        public Vector3 Position
        {
            get { return position; }
            set { position = value; }
        }

        public PowerUpType TypeOfPowerUp
        {
            get { return typeOfPowerUp; }
            set { typeOfPowerUp = value; }
        }
        #endregion

        #region intialization


        public PowerUp(Model model, Texture2D texture, PowerUpType powerUpType, Vector3 position)
        {

            this.typeOfPowerUp = powerUpType;
            this.model = model;
            this.position = position;
            this.lifeTime = 10;


            this.billboardTexture = texture;
            this.quad = new Quad(this.position, Vector3.Forward, Vector3.Up, 1, 1);
            this.scaleFactor = 3;

            Vector3 size = new Vector3(400, 400, 400);
            //Vector3 size=new Vector3(400,1000,400); // bigger bounding box for easier pick up            
            this.boundingBox = new BoundingBox(position - size, position + size);

        }

        #endregion

        #region methods
        public void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (goUp)
            {
                scaleFactor += 0.5f * elapsed;
            }
            else
            {
                scaleFactor -= 0.5f * elapsed;
            }

            if (scaleFactor > 3.1)
            {
                goUp = false;
            }
            else if (scaleFactor < 2.9)
            {
                goUp = true;
            }
        }


        public void DrawOrtho(float position)
        {
            int width = LabyrinthGame.GDevice.ScissorRectangle.Width;
            int height = LabyrinthGame.GDevice.ScissorRectangle.Height;
            float scaleFactor = width / 2400f;
            float translateFactor = (int)((width * 800 / 1200)) / 800f;

            world = Matrix.CreateOrthographic(width, height, 0.1f, 10000);
            Matrix translate = Matrix.CreateTranslation(1000 * Vector3.Forward + (height / 2f - 55 * translateFactor) * Vector3.Down + (width / 2f-70*translateFactor) * Vector3.Left + Vector3.Right * position);
            Matrix scale = Matrix.CreateScale(scaleFactor);

            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            LabyrinthGame.GDevice.Viewport = new Viewport(0, 0, width, height);
            LabyrinthGame.GDevice.BlendState = BlendState.AlphaBlend;
            LabyrinthGame.GDevice.DepthStencilState = DepthStencilState.Default;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World =scale* transforms[mesh.ParentBone.Index] * translate;
                    // Use the matrices provided by the chase camera
                    effect.View = Matrix.Identity;
                    effect.Projection = world;

                    if (mesh.Name == "Plane")
                    {
                        effect.LightingEnabled = false;
                        effect.TextureEnabled = true;
                        effect.Texture = billboardTexture;
                        effect.SpecularColor = new Vector3(1f, 1f, 0f);
                        effect.AmbientLightColor = new Vector3(0, 0, 0);
                        effect.DiffuseColor = new Vector3(1f, 1f, 1f);
                        effect.EmissiveColor = new Vector3(0.2f, 0.2f, 0.2f);
                        effect.SpecularPower = 100;
                        effect.Alpha = 1f - (MAX_LIFE - lifeTime) / (float)MAX_LIFE;
                    }
                    else
                    {
                        effect.TextureEnabled = false;
                        effect.LightingEnabled = true;
                        effect.SpecularColor = new Vector3(1f, 1f, 0f);
                        //good
                        effect.AmbientLightColor = new Vector3(0.2f, 0.6f, 0.2f);
                        effect.EmissiveColor = new Vector3(0.2f, 0.6f, 0.2f);
                        //bad
                        //effect.AmbientLightColor = new Vector3(0.6f, 0.2f, 0.2f);
                        //effect.EmissiveColor = new Vector3(0.6f, 0.2f, 0.2f);

                        effect.DiffuseColor = new Vector3(1f, 1f, 1f);
                        effect.SpecularPower = 100;
                        effect.Alpha = 0.2f;

                    }

                }

                //if (mesh.Name != "Plane") continue;

                mesh.Draw();
            }

        }



        public void Draw(Camera camera)
        {


            Vector3 direction = this.position - camera.Position; //new Vector3(camera.LookAt.X, 0, camera.LookAt.Z);
            direction.Y = 0;
            direction.Normalize();
            world = Matrix.Identity;
            world.Forward = direction;
            world.Up = Vector3.Up;
            world.Right = Vector3.Cross(direction, Vector3.Up);

            Matrix translate = Matrix.CreateTranslation(position);
            Matrix scale = Matrix.CreateScale(scaleFactor);
            world = scale * world * translate;

            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            LabyrinthGame.GDevice.BlendState = BlendState.AlphaBlend;
            LabyrinthGame.GDevice.DepthStencilState = DepthStencilState.Default;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = transforms[mesh.ParentBone.Index] * world;
                    // Use the matrices provided by the chase camera
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;

                    if (mesh.Name == "Plane")
                    {
                        effect.LightingEnabled = false;
                        effect.TextureEnabled = true;
                        effect.Texture = billboardTexture;
                        effect.SpecularColor = new Vector3(1f, 1f, 0f);
                        effect.AmbientLightColor = new Vector3(0, 0, 0);
                        effect.DiffuseColor = new Vector3(1f, 1f, 1f);
                        effect.EmissiveColor = new Vector3(0.2f, 0.2f, 0.2f);
                        effect.SpecularPower = 100;
                        effect.Alpha = 1f;
                    }
                    else
                    {
                        effect.TextureEnabled = false;
                        effect.LightingEnabled = true;
                        effect.SpecularColor = new Vector3(1f, 1f, 0f);
                        effect.AmbientLightColor = new Vector3(0.2f, 0.2f, 0.2f);
                        effect.DiffuseColor = new Vector3(1f, 1f, 1f);
                        effect.EmissiveColor = new Vector3(0.2f, 0.2f, 0.2f);
                        effect.SpecularPower = 100;
                        effect.Alpha = 0.2f;

                    }

                }

                //if (mesh.Name != "Plane") continue;

                mesh.Draw();
            }


        }
        #endregion
    }
}
